home *** CD-ROM | disk | FTP | other *** search
- /*
- * A U X . C
- *
- * EE/CIS Computer Lab
- * Department of Computer and Information Sciences
- * Department of Electrical Engineering
- * University of Delaware
- *
- * REVISION HISTORY:
- *
- * $Revision: 1.4 $
- *
- * $Log: aux.c,v $
- * Revision 1.4 86/01/14 14:04:40 galvin
- *
- * Change nameof so it does not delete the comment associated
- * with an address (it is probably the senders full name).
- *
- * Change skin() to use MMDF's parsadr to find the route.
- *
- * Add routeq() to use when comparing routes. The intent is not to
- * compare the comment part of address when looking for duplicate entries.
- *
- * Revision 1.3 85/12/18 13:31:12 galvin
- * Change alter to use the MMDF locking routines.
- *
- * Comment out a call to exit which just didn't look like it belonged.
- *
- * Revision 1.2 85/12/18 13:28:48 galvin
- * Added comment header for revision history.
- *
- *
- */
-
- /*
- * Copyright (c) 1980 Regents of the University of California.
- * All rights reserved. The Berkeley software License Agreement
- * specifies the terms and conditions for redistribution.
- */
-
- #ifndef lint
- static char *sccsid = "@(#)aux.c 5.4 (Berkeley) 1/13/86";
- #endif not lint
-
- #include "./rcv.h"
- #include <sys/stat.h>
- #include <ctype.h>
-
- /*
- * Mail -- a mail program
- *
- * Auxiliary functions.
- */
-
- /*
- * Return a pointer to a dynamic copy of the argument.
- */
-
- char *
- savestr(str)
- char *str;
- {
- register char *cp, *cp2, *top;
-
- for (cp = str; *cp; cp++)
- ;
- top = salloc(cp-str + 1);
- if (top == NOSTR)
- return(NOSTR);
- for (cp = str, cp2 = top; *cp; cp++)
- *cp2++ = *cp;
- *cp2 = 0;
- return(top);
- }
-
- #ifdef NOT_USED
- /*
- * Copy the name from the passed header line into the passed
- * name buffer. Null pad the name buffer.
- */
-
- copyname(linebuf, nbuf)
- char *linebuf, *nbuf;
- {
- register char *cp, *cp2;
-
- for (cp = linebuf + 5, cp2 = nbuf; *cp != ' ' && cp2-nbuf < 8; cp++)
- *cp2++ = *cp;
- while (cp2-nbuf < 8)
- *cp2++ = 0;
- }
- #endif NOT_USED
-
- /*
- * Announce a fatal error and die.
- */
-
- panic(str)
- char *str;
- {
- prs("panic: ");
- prs(str);
- prs("\n");
- exit(1);
- }
-
- #ifdef NOT_USED
- /*
- * Catch stdio errors and report them more nicely.
- */
-
- _error(str)
- char *str;
- {
- prs("Stdio Error: ");
- prs(str);
- prs("\n");
- abort();
- }
- #endif NOT_USED
-
- /*
- * Print a string on diagnostic output.
- */
-
- prs(str)
- char *str;
- {
- register char *s;
-
- for (s = str; *s; s++)
- ;
- write(2, str, s-str);
- }
-
- /*
- * Touch the named message by setting its MTOUCH flag.
- * Touched messages have the effect of not being sent
- * back to the system mailbox on exit.
- */
-
- touch(mesg)
- {
- register struct message *mp;
-
- if (mesg < 1 || mesg > msgCount)
- return;
- mp = &message[mesg-1];
- mp->m_flag |= MTOUCH;
- if ((mp->m_flag & MREAD) == 0)
- mp->m_flag |= MREAD|MSTATUS;
- }
-
- /*
- * Test to see if the passed file name is a directory.
- * Return true if it is.
- */
-
- isdir(name)
- char name[];
- {
- struct stat sbuf;
-
- if (stat(name, &sbuf) < 0)
- return(0);
- return((sbuf.st_mode & S_IFMT) == S_IFDIR);
- }
-
- /*
- * Count the number of arguments in the given string raw list.
- */
-
- argcount(argv)
- char **argv;
- {
- register char **ap;
-
- for (ap = argv; *ap != NOSTR; ap++)
- ;
- return(ap-argv);
- }
-
- /*
- * Given a file address, determine the
- * block number it represents.
- */
-
- blockof(off)
- off_t off;
- {
- off_t a;
-
- a = off >> 9;
- a &= 077777;
- return((int) a);
- }
-
- /*
- * Take a file address, and determine
- * its offset in the current block.
- */
-
- offsetof(off)
- off_t off;
- {
- off_t a;
-
- a = off & 0777;
- return((int) a);
- }
-
- /*
- * Return the desired header line from the passed message
- * pointer (or NOSTR if the desired header field is not available).
- */
-
- char *
- hfield(field, mp)
- char field[];
- struct message *mp;
- {
- register FILE *ibuf;
- char linebuf[LINESIZE];
- register int lc;
-
- ibuf = setinput(mp);
- if ((lc = mp->m_lines) <= 0)
- return(NOSTR);
- do {
- lc = gethfield(ibuf, linebuf, lc);
- #ifdef DEBUG
- if (debug)
- printf("got header \"%s\"\n", linebuf);
- #endif DEBUG
- if (lc == -1)
- return(NOSTR);
- if (ishfield(linebuf, field))
- return(savestr(hcontents(linebuf)));
- } while (lc > 0);
- return(NOSTR);
- }
-
- /*
- * Return the next header field found in the given message.
- * Return > 0 if something found, <= 0 elsewise.
- * Must deal with \ continuations & other such fraud.
- */
-
- gethfield(f, linebuf, rem)
- register FILE *f;
- char linebuf[];
- register int rem;
- {
- char line2[LINESIZE];
- long loc;
- register char *cp, *cp2;
- register int c;
-
-
- for (;;) {
- if (rem <= 0)
- return(-1);
- if (readline(f, linebuf) < 0)
- return(-1);
- rem--;
- if (strlen(linebuf) == 0)
- return(-1);
- if (isspace(linebuf[0]))
- continue;
- if (linebuf[0] == '>')
- continue;
- cp = index(linebuf, ':');
- if (cp == NOSTR)
- continue;
- for (cp2 = linebuf; cp2 < cp; cp2++)
- if (isdigit(*cp2))
- continue;
-
- /*
- * I guess we got a headline.
- * Handle wraparounding
- */
-
- for (;;) {
- if (rem <= 0)
- break;
- #ifdef CANTELL
- loc = ftell(f);
- if (readline(f, line2) < 0)
- break;
- rem--;
- if (!isspace(line2[0])) {
- fseek(f, loc, 0);
- rem++;
- break;
- }
- #else
- c = getc(f);
- ungetc(c, f);
- if (!isspace(c) || c == '\n')
- break;
- if (readline(f, line2) < 0)
- break;
- rem--;
- #endif
- cp2 = line2;
- for (cp2 = line2; *cp2 != 0 && isspace(*cp2); cp2++)
- ;
- if (strlen(linebuf) + strlen(cp2) >= LINESIZE-2)
- break;
- cp = &linebuf[strlen(linebuf)];
- while (cp > linebuf &&
- (isspace(cp[-1]) || cp[-1] == '\\'))
- cp--;
- *cp++ = ' ';
- for (cp2 = line2; *cp2 != 0 && isspace(*cp2); cp2++)
- ;
- strcpy(cp, cp2);
- }
- if ((c = strlen(linebuf)) > 0) {
- cp = &linebuf[c-1];
- while (cp > linebuf && isspace(*cp))
- cp--;
- *++cp = 0;
- }
- return(rem);
- }
- /* NOTREACHED */
- }
-
- /*
- * Check whether the passed line is a header line of
- * the desired breed.
- */
-
- ishfield(linebuf, field)
- char linebuf[], field[];
- {
- register char *cp;
- register int c;
-
- if ((cp = index(linebuf, ':')) == NOSTR)
- return(0);
- if (cp == linebuf)
- return(0);
- cp--;
- while (cp > linebuf && isspace(*cp))
- cp--;
- c = *++cp;
- *cp = 0;
- if (icequal(linebuf ,field)) {
- *cp = c;
- return(1);
- }
- *cp = c;
- return(0);
- }
-
- /*
- * Extract the non label information from the given header field
- * and return it.
- */
-
- char *
- hcontents(hfld)
- char hfld[];
- {
- register char *cp;
-
- if ((cp = index(hfld, ':')) == NOSTR)
- return(NOSTR);
- cp++;
- while (*cp && isspace(*cp))
- cp++;
- return(cp);
- }
-
- /*
- * Compare two strings, ignoring case.
- */
-
- icequal(s1, s2)
- register char *s1, *s2;
- {
-
- while (raise(*s1++) == raise(*s2))
- if (*s2++ == 0)
- return(1);
- return(0);
- }
-
- /*
- * Copy a string, lowercasing it as we go.
- */
- istrcpy(dest, src)
- char *dest, *src;
- {
- register char *cp, *cp2;
-
- cp2 = dest;
- cp = src;
- do {
- *cp2++ = little(*cp);
- } while (*cp++ != 0);
- }
-
- /*
- * The following code deals with input stacking to do source
- * commands. All but the current file pointer are saved on
- * the stack.
- */
-
- static int ssp = -1; /* Top of file stack */
- struct sstack {
- FILE *s_file; /* File we were in. */
- int s_cond; /* Saved state of conditionals */
- int s_loading; /* Loading .mailrc, etc. */
- } sstack[NOFILE];
-
- /*
- * Pushdown current input file and switch to a new one.
- * Set the global flag "sourcing" so that others will realize
- * that they are no longer reading from a tty (in all probability).
- */
-
- source(name)
- char name[];
- {
- register FILE *fi;
- register char *cp;
-
- if ((cp = expand(name)) == NOSTR)
- return(1);
- if ((fi = fopen(cp, "r")) == NULL) {
- perror(cp);
- return(1);
- }
- if (ssp >= NOFILE - 2) {
- printf("Too much \"sourcing\" going on.\n");
- fclose(fi);
- return(1);
- }
- sstack[++ssp].s_file = input;
- sstack[ssp].s_cond = cond;
- sstack[ssp].s_loading = loading;
- loading = 0;
- cond = CANY;
- input = fi;
- sourcing++;
- return(0);
- }
-
- #ifdef NOT_USED
- /*
- * Source a file, but do nothing if the file cannot be opened.
- */
-
- source1(name)
- char name[];
- {
- register int f;
-
- if ((f = open(name, 0)) < 0)
- return(0);
- close(f);
- return(source(name));
- }
- #endif NOT_USED
-
- /*
- * Pop the current input back to the previous level.
- * Update the "sourcing" flag as appropriate.
- */
-
- unstack()
- {
- if (ssp < 0) {
- printf("\"Source\" stack over-pop.\n");
- sourcing = 0;
- return;
- }
- fclose(input);
- if (cond != CANY)
- printf("Unmatched \"if\"\n");
- cond = sstack[ssp].s_cond;
- loading = sstack[ssp].s_loading;
- input = sstack[ssp--].s_file;
- if (ssp < 0)
- sourcing = loading;
- }
-
- /*
- * Touch the indicated file.
- * This is nifty for the shell.
- * If we have the utimes() system call, this is better served
- * by using that, since it will work for empty files.
- * The utime() system call can be used if necessary.
- * On non-utime systems, we must sleep a second, then read.
- */
- #ifdef UTIMES
- #include <sys/time.h>
- #endif UTIMES
-
- alter(name)
- char name[];
- {
- #ifdef UTIMES
- struct stat statb;
- struct timeval tp[2];
- struct timezone tzp;
- #else UTIMES
- #ifdef UTIME
- struct stat statb;
- time_t time();
- time_t time_p[2];
- #else UTIME
- register int f;
- char w;
- #endif UTIME
- #endif UTIMES
-
- #ifdef UTIMES
- if (stat(name, &statb) < 0)
- return;
- if (gettimeofday(&tp[0], &tzp) < 0)
- return;
- tp[1] = tp[0];
- utimes(name, tp);
- #else UTIMES
- #ifdef UTIME
- if (stat(name, &statb) < 0)
- return;
- time_p[0] = time((long *) 0) + 1;
- time_p[1] = statb.st_mtime;
- utime(name, time_p);
- #else UTIME
- sleep(1);
- if ((f = lk_open(name, 0, (char *) 0, (char *) 0, 5)) < 0)
- return;
- read(f, &w, 1);
- lk_close(f, name, (char *) 0, (char *) 0);
- /* exit(0); /* was this really intended ?? */
- #endif UTIME
- #endif UTIMES
- }
-
- /*
- * Examine the passed line buffer and
- * return true if it is all blanks and tabs.
- */
-
- blankline(linebuf)
- char linebuf[];
- {
- register char *cp;
-
- for (cp = linebuf; *cp; cp++)
- if (*cp != ' ' && *cp != '\t')
- return(0);
- return(1);
- }
-
- /*
- * Get sender's name from this message.
- */
- char *
- nameof(mp, reptype)
- register struct message *mp;
- {
- register char *cp, *cp2;
-
- cp = name1(mp, reptype);
- if (reptype != 0 || charcount(cp, '!') < 2)
- return(cp);
- cp2 = rindex(cp, '!');
- cp2--;
- while (cp2 > cp && *cp2 != '!')
- cp2--;
- if (*cp2 == '!')
- return(cp2 + 1);
- return(cp);
- }
-
- #ifdef NOT_USED
- /*
- * Skin an arpa net address.
- *
- * We borrow adrparse from MMDF to do this.
- */
- char *
- skin(name)
- char *name;
- {
- char nbuf[256], namecp[256], mbx[256], host[256];
-
- strcpy(namecp, name); /* make it local */
- parsadr(namecp, NOSTR, mbx, host);
- if( *host )
- sprintf(nbuf, "%s@%s", mbx, host);
- else
- strcpy(nbuf, mbx);
- return(savestr(nbuf));
- }
- #endif NOT_USED
-
- /*
- * Fetch the sender's name from the passed message.
- * Reptype can be
- * 0 -- get sender's name for display purposes
- * 1 -- get sender's name for reply
- * 2 -- get sender's name for Reply
- */
-
- char *
- name1(mp, reptype)
- register struct message *mp;
- {
- char namebuf[LINESIZE];
- char linebuf[LINESIZE];
- register char *cp, *cp2;
- register FILE *ibuf;
- int first = 1;
-
- if ((cp = hfield("from", mp)) != NOSTR)
- return(cp);
- if (reptype == 0 && (cp = hfield("sender", mp)) != NOSTR)
- return(cp);
- ibuf = setinput(mp);
- copy("", namebuf);
- if (readline(ibuf, linebuf) <= 0)
- return(savestr(namebuf));
- newname:
- for (cp = linebuf; *cp != ' '; cp++)
- ;
- while (any(*cp, " \t"))
- cp++;
- for (cp2 = &namebuf[strlen(namebuf)]; *cp && !any(*cp, " \t") &&
- cp2-namebuf < LINESIZE-1; *cp2++ = *cp++)
- ;
- *cp2 = '\0';
- if (readline(ibuf, linebuf) <= 0)
- return(savestr(namebuf));
- if ((cp = index(linebuf, 'F')) == NULL)
- return(savestr(namebuf));
- if (strncmp(cp, "From", 4) != 0)
- return(savestr(namebuf));
- while ((cp = index(cp, 'r')) != NULL) {
- if (strncmp(cp, "remote", 6) == 0) {
- if ((cp = index(cp, 'f')) == NULL)
- break;
- if (strncmp(cp, "from", 4) != 0)
- break;
- if ((cp = index(cp, ' ')) == NULL)
- break;
- cp++;
- if (first) {
- copy(cp, namebuf);
- first = 0;
- } else
- strcpy(rindex(namebuf, '!')+1, cp);
- strcat(namebuf, "!");
- goto newname;
- }
- cp++;
- }
- return(savestr(namebuf));
- }
-
- /*
- * Count the occurances of c in str
- */
- charcount(str, c)
- char *str;
- {
- register char *cp;
- register int i;
-
- for (i = 0, cp = str; *cp; cp++)
- if (*cp == c)
- i++;
- return(i);
- }
-
- #ifdef NOT_USED
- /*
- * See if the string is a number.
- */
-
- numeric(str)
- char str[];
- {
- register char *cp = str;
-
- while (*cp)
- if (!isdigit(*cp++))
- return(0);
- return(1);
- }
- #endif NOT_USED
-
- /*
- * Are any of the characters in the two strings the same?
- */
-
- anyof(s1, s2)
- register char *s1, *s2;
- {
- register int c;
-
- while (c = *s1++)
- if (any(c, s2))
- return(1);
- return(0);
- }
-
- /*
- * See if the given header field is supposed to be ignored.
- */
- isign(field)
- char *field;
- {
- char realfld[BUFSIZ];
-
- /*
- * Lower-case the string, so that "Status" and "status"
- * will hash to the same place.
- */
- istrcpy(realfld, field);
-
- if (nretained > 0)
- return (!member(realfld, retain));
- else
- return (member(realfld, ignore));
- }
-
- member(realfield, table)
- register char *realfield;
- register struct ignore **table;
- {
- register struct ignore *igp;
-
- for (igp = table[hash(realfield)]; igp != 0; igp = igp->i_link)
- if (equal(igp->i_field, realfield))
- return (1);
-
- return (0);
- }
-
- /*
- * When comparing addresses, let's compare only mailbox@host, not
- * a string compare. Let's use a case insensitive string compare
- * on the route. Return values are same as icequal().
- */
-
- routeq(adr1, adr2)
- char *adr1, *adr2;
- {
- char a1[BUFSIZ], a2[BUFSIZ], mbx[BUFSIZ], host[BUFSIZ];
-
- strcpy(a1, adr1); strcpy(a2, adr2); /* make them local */
- parsadr(a1, NOSTR, mbx, host);
- if (*host)
- sprintf(a1, "%s@%s", mbx, host);
- else
- sprintf(a1, "%s", mbx);
- parsadr(a2, NOSTR, mbx, host);
- if (*host)
- sprintf(a2, "%s@%s", mbx, host);
- else
- sprintf(a2, "%s", mbx);
- return(icequal(a1, a2));
- }
-